home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tech Arsenal 1
/
Tech Arsenal (Arsenal Computer).ISO
/
tek-01
/
ohlcpio.zip
/
MAIN.C
< prev
next >
Wrap
C/C++ Source or Header
|
1990-07-07
|
7KB
|
280 lines
/* main.c - main program and argument processing for cpio.
Copyright (C) 1988, 1989, 1990 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
/* Written by Philip A. Nelson and David MacKenzie. */
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#ifndef S_IFLNK
#define lstat stat
#endif
#ifdef USG
#include <string.h>
#else
#include <strings.h>
#endif
#include <getopt.h>
#include "cpio.h"
#include "dstring.h"
#include "extern.h"
int lstat ();
int stat ();
struct option long_opts[] =
{
{"binary", 0, &binary_flag, TRUE},
{"block-size", 1, 0, 130},
{"create", 0, 0, 'o'},
{"dereference", 0, 0, 'L'},
{"extract", 0, 0, 'i'},
{"link", 0, &link_flag, TRUE},
{"list", 0, &table_flag, TRUE},
{"make-directories", 0, &create_dir_flag, TRUE},
{"nonmatching", 0, ©_matching_files, FALSE},
{"numeric-uid-gid", 0, &numeric_uid, TRUE},
{"pass-through", 0, 0, 'p'},
{"portability", 0, &portability_flag, TRUE},
{"preserve-modification-time", 0, &retain_time_flag, TRUE},
{"rename", 0, &rename_flag, TRUE},
{"reset-access-time", 0, &reset_time_flag, TRUE},
{"unconditional", 0, &unconditional_flag, TRUE},
{"verbose", 0, &verbose_flag, TRUE},
{"version", 0, 0, 'V'},
{0, 0, 0, 0}
};
/* Print usage message and exit with error. */
void
usage ()
{
fprintf (stderr, "\
Usage: %s {-o|+create} [-abcvBLV] [+reset-access-time] [+binary]\n\
[+portability] [+verbose] [+block-size=blocks] [+dereference]\n\
[+version] < name-list > archive\n\
\n\
%s {-i|+extract} [-bcdfmnrtuvBV] [+binary] [+portability]\n\
[+make-directories] [+nonmatching] [+preserve-modification-time]\n\
[+numeric-uid-gid] [+rename] [+list] [+unconditional] [+verbose]\n\
[+block-size=blocks] [+version] [pattern...] < archive\n\
\n\
%s {-p|+pass-through} [-adlLmuvV] [+reset-access-time]\n\
[+make-directories] [+link] [+preserve-modification-time]\n\
[+unconditional] [+verbose] [+dereference] [+version]\n\
destination-directory < name-list\n",
program_name, program_name, program_name);
exit (2);
}
/* Process the arguments. Set all options and set up the copy pass
directory or the copy in patterns. */
void
process_args (argc, argv)
int argc;
char *argv[];
{
extern char *version_string;
void (*copy_in) (); /* Work around for pcc bug. */
void (*copy_out) ();
int c;
int longind;
if (argc < 2)
usage ();
xstat = lstat;
while ((c = getopt_long (argc, argv, "abBcdfilLmnoprtuvV", long_opts,
&longind)) != EOF)
{
switch (c)
{
case 0: /* A long option that just sets a flag. */
break;
case 'a': /* Reset access times. */
reset_time_flag = TRUE;
break;
case 'b': /* Use the nonportable format. */
binary_flag = TRUE;
break;
case 'B': /* Set block size to 5120. */
io_block_size = 5120;
break;
case 130: /* +block-size */
io_block_size = atoi (optarg);
if (io_block_size < 1)
error (2, 0, "invalid block size");
io_block_size *= 512;
break;
case 'c': /* Use the portable format. */
portability_flag = TRUE;
break;
case 'd': /* Create directories where needed. */
create_dir_flag = TRUE;
break;
case 'f': /* Only copy files not matching patterns. */
copy_matching_files = FALSE;
break;
case 'i': /* Copy-in mode. */
if (copy_function != 0)
usage ();
copy_function = process_copy_in;
break;
case 'l': /* Link files when possible. */
link_flag = TRUE;
break;
case 'L': /* Dereference symbolic links. */
xstat = stat;
break;
case 'm': /* Retain previous file modify times. */
retain_time_flag = TRUE;
break;
case 'n': /* Long list owner and group as numbers. */
numeric_uid = TRUE;
break;
case 'o': /* Copy-out mode. */
if (copy_function != 0)
usage ();
copy_function = process_copy_out;
break;
case 'p': /* Copy-pass mode. */
if (copy_function != 0)
usage ();
copy_function = process_copy_pass;
break;
case 'r': /* Interactively rename. */
rename_flag = TRUE;
break;
case 't': /* Only print a list. */
table_flag = TRUE;
break;
case 'u': /* Replace all! Unconditionally! */
unconditional_flag = TRUE;
break;
case 'v': /* Verbose! */
verbose_flag = TRUE;
break;
case 'V':
printf ("%s", version_string);
break;
default:
usage ();
}
}
/* Do error checking and look at other args. */
if (copy_function == 0)
{
if (table_flag)
copy_function = process_copy_in;
else
usage ();
}
if ((!table_flag || !verbose_flag) && numeric_uid)
usage ();
/* Work around for pcc bug. */
copy_in = process_copy_in;
copy_out = process_copy_out;
if (copy_function == copy_in)
{
if (link_flag || reset_time_flag || xstat != lstat
|| (binary_flag && portability_flag))
usage ();
if (!binary_flag && !portability_flag)
binary_flag = portability_flag = TRUE;
num_patterns = argc - optind;
save_patterns = &argv[optind];
}
else if (copy_function == copy_out)
{
if (argc != optind || create_dir_flag || rename_flag
|| table_flag || unconditional_flag || link_flag
|| retain_time_flag || (binary_flag && portability_flag))
usage ();
}
else
{
if (argc - 1 != optind || binary_flag || portability_flag
|| table_flag || rename_flag)
usage ();
directory_name = argv[optind];
}
}
/* Initialize the input and output buffers to their proper size and
initialize all variables associated with the input and output
buffers. */
void
initialize_buffers ()
{
input_buffer = (char *) xmalloc (io_block_size);
in_buff = input_buffer;
input_size = 0;
input_bytes = 0;
/* Leave space for an `int' sentinel for `empty_output_buffer'. */
output_buffer = (char *) xmalloc (io_block_size + sizeof (int) * 2);
out_buff = output_buffer;
output_size = 0;
output_bytes = 0;
}
void
main (argc, argv)
int argc;
char *argv[];
{
program_name = argv[0];
umask (0);
process_args (argc, argv);
initialize_buffers ();
(*copy_function) ();
exit (0);
}